// 获取值的原始类型字符串，例如 [object Object]
const _toString = Object.prototype.toString;

export function isArray(val: any) {
	return _toString.call(val) === '[object Array]';
}

export function isPlainObject(val: any) {
	return _toString.call(val) === '[object Object]';
}

export function forEach(obj: any, fn: Function) {
	if (obj === null || obj === undefined) return;
	if (typeof obj !== 'object') obj = [obj];
	if (isArray(obj)) {
		for (let i = 0, l = obj.length; i < l; i++) {
			fn.call(null, obj[i], i, obj);
		}
	} else {
		for (const k in obj) {
			if (Object.prototype.hasOwnProperty.call(obj, k)) {
				fn.call(null, obj[k], k, obj);
			}
		}
	}
}

// 对象深合并
export function merge(...args: any[]) {
	const result = {};
	for (let i = 0, l = args.length; i < l; i++) {
		if (isPlainObject(args[i])) {
			forEach(args[i], (val: any, key: any) => {
				// @ts-ignore
				result[key] = assign(result[key], val);
			});
		}
	}
	return result;
}

export function assign(target: any, source: any) {
	if (isPlainObject(target) && isPlainObject(source)) {
		return merge(target, source);
	} else if (isPlainObject(source)) {
		return merge({}, source);
	} else if (isArray(source)) {
		return source.slice();
	}
	return source;
}

export function tryCatch(fn: Function) {
	return function(...args: any[]) {
		try {
			return fn.apply(fn, args);
		} catch (error) {
			console.error(error);
		}
	};
}

export function setObjToUrlParams(baseUrl: string, obj: any): string {
	let parameters = '';
	for (const key in obj) {
		parameters += key + '=' + encodeURIComponent(obj[key]) + '&';
	}
	parameters = parameters.replace(/&$/, '');
	return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters;
}
